home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_489
/
mkbmap
/
mkbmap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
28KB
|
959 lines
/* Amiga bitmapped font builder. File "mkbmap.c".
* (C) Adrian Aylward 1991
*
* You may freely copy, use, and modify this file.
*
* This program prints builds an Amiga format bitmapped screen font file
* from the corresponding PostScript font, using post.library. It is totally
* Amiga specific.
*
* The program was tested using Lattice C V5.05. It has various Lattice
* dependencies.
*
* This is version 1.0.
*/
# include <dos.h>
# include <exec/exec.h>
# include <libraries/diskfont.h>
# include <proto/diskfont.h>
# include <proto/dos.h>
# include <proto/exec.h>
# include <string.h>
# include <stdarg.h>
# include <stdio.h>
# include "postlib.h"
# undef POSTVERNO
# define POSTVERNO 15 /* We need post.library version 1.5+ */
/* The following definitions appear to be missing from the Lattice headers */
# ifdef LATTICE
extern struct FontContentsHeader *NewFontContents(BPTR lock, char *name);
extern void DisposeFontContents(struct FontContentsHeader *fc);
# pragma libcall DiskfontBase NewFontContents 2a 9802 ; d0 = (a0, a1)
# pragma libcall DiskfontBase DisposeFontContents 30 901 ; (a1)
# endif
/* Assembler routines */
extern void insertftrap(void);
extern void deleteftrap(void);
/* Object module hunks */
# define Hunk_Header 0x3F3
# define Hunk_Code 0x3E9
# define Hunk_Reloc32 0x3EC
# define Hunk_End 0x3F2
# define MOVFFD0RTS 0x70FF4E75
/* External data (initialised to zero) */
char *argbmapfile, *argfontname, *argpointsizes;
char *argstartupfile, *argencodingfile;
int optfontencoding, optnew;
int optmonospaced, optbold, optitalic, opttrace;
int optden, optxden, optyden, optbaseline, optwidth;
int pointc, pointn, pointv[100];
int retcode;
int arec;
struct library *PSbase;
struct PSparm parm;
APTR functab[10];
int ftrapset;
int pointsize;
char namebuf[100 + 5];
char psstring[200];
int pserror;
int lochar, hichar;
int baseline, nomwidth, nomcount;
int llx[256], lly[256], urx[256], ury[256];
int cposx, cposy;
void *fontmem;
int baselen;
int maxfontlen, maxcharlen, maxmodulo, maxwidth;
int actfontlen, actcharlen, actmodulo, actwidth;
int hunklen, hunknum, *hunkptr;
BPTR fdlock, cdlock, newfh;
struct FontContentsHeader *fcheader;
struct DiskFontHeader *dfheader;
char *chardata;
short *charloc, *charspace, *charkern;
/* Routines */
extern int strtoint(char **sp, int *ip);
extern char *buildfnumname(char *nbuf, char *name, int num);
extern char *buildfdirname(char *nbuf, char *name, int type);
extern void pstrace(char *format, ...);
extern void pssintf(char *format, ...);
extern void __saveds setbbox(int ch, int lx, int ly, int rx, int uy);
extern void __saveds setcpos(int cpx, int cpy);
/* Main program */
void main(int argc, char **argv)
{ char *s, *t;
int *ip, i, l, ch;
int y1, y2, z1, z2, zz, ww;
/* Parse arguments. No workbench startup */
optxden = optyden = 75;
optbaseline = optwidth = -1;
lochar = 32;
hichar = 255;
if (argc == 0) goto tidyexit;
argv++;
argc--;
if (argc == 0 || (argc == 1 && strcmp(*argv, "?") == 0)) goto query;
while (argc)
{ s = *argv;
if (*s != '-') break;
argv++;
argc--;
if (strcmp(s, "--") == 0) break;
s++;
for (;;)
{ ch = *s++;
if (ch == 0) break;
switch (ch)
{ case 'S': case 's':
if (argc == 0) goto badargs;
argstartupfile = *argv++;
argc--;
case 'E': case 'e':
if (argc == 0) goto badargs;
argencodingfile = *argv++;
argc--;
case 'F': case 'f':
optfontencoding = 1;
continue;
case 'N': case 'n':
optnew = 1;
continue;
case 'D': case 'd':
ip = &optden;
break;
case 'X': case 'x':
ip = &optxden;
break;
case 'Y': case 'y':
ip = &optyden;
break;
case 'Z': case 'z':
ip = &optbaseline;
break;
case 'L': case 'l':
ip = &lochar;
break;
case 'W': case 'w':
ip = &optwidth;
break;
case 'H': case 'h':
ip = &hichar;
break;
case 'M': case 'm':
optmonospaced = 1;
continue;
case 'B': case 'b':
optbold = 1;
continue;
case 'I': case 'i':
optitalic = 1;
continue;
case 'T': case 't':
opttrace = 1;
continue;
default:
fprintf(stderr, "mkbmap: unknown option \"-%c\"", ch);
goto badusage;
}
if (!strtoint(&s, ip)) goto badargs;
if (ip == &optden) optxden = optyden = optden;
}
if (*s == '-' && *(s + 1) == 0) break;
}
if (lochar > hichar || hichar > 255)
{ fprintf(stderr, "mkbmap: LoChar/HiChar out of range "
"(0 <= Lo <= Hi <= 255)\n");
goto errorexit;
}
if (argc != 1 && argc != 3) goto badargs;
argbmapfile = argv[0];
if (argc == 3)
{ argfontname = argv[1];
argpointsizes = argv[2];
s = argpointsizes;
while (*s)
{ i = 0;
for (;;)
{ ch = *s;
if (ch == 0) break;
s++;
if (ch == ',') break;
if (ch >= '0' && ch <= '9')
i = i * 10 + (ch - '0');
else
goto badargs;
}
if (i != 0)
{ if (i < 5 || i > 500)
{ fprintf(stderr, "mkbmap: point size %d out of range "
"(5 - 500)\n", pointsize);
goto errorexit;
}
if (pointc == 100) goto badargs;
pointv[pointc++] = i;
}
}
}
if (pointc == 0) goto newfont;
if (argencodingfile == NULL) argencodingfile = "PSFonts:encoding.ps";
if (argstartupfile == NULL) argstartupfile = "PSFonts:init.ps";
/* Initialise the PostScript library */
pstrace("%% Opening PostScript library\n");
PSbase = OpenLibrary("post.library", POSTVERNO);
if (PSbase == NULL)
{ fprintf(stderr, "mkbmap: can't open post.library (V15+)\n");
goto errorexit;
}
pstrace("%% Initialising PostScript activation\n");
parm.page.buf[0] = namebuf;
parm.page.len = 100;
parm.page.depth = 1;
parm.page.xoff = 0;
parm.page.yoff = 0;
parm.page.xbytes = 10;
parm.page.xsize = 80;
parm.page.ysize = 10;
parm.page.ybase = 0;
parm.page.yheight = 10;
parm.page.xden = 72;
parm.page.yden = 72;
parm.page.ydir = -1;
parm.memvlen = 20000;
parm.memflen = 10000;
parm.memllen = defmemllen;
parm.memhlen = minmemhlen;
parm.infh = Input();
parm.outfh = Output();
parm.errfh = Output();
parm.funcmax = 2;
functab[0] = (APTR) setbbox;
functab[1] = (APTR) setcpos;
parm.functab = functab;
insertftrap();
ftrapset = 1;
arec = PScreateact(&parm);
if (arec == 0)
{ fprintf(stderr, "mkbmap: post.library can't get memory\n");
goto errorexit;
}
if ((unsigned) arec <= errmax)
{ pserror = arec;
arec = 0;
goto pserror;
}
/* Load the startup file */
pstrace("%% Loading startup file\n");
pssintf("(%.100s) run clear\n", argstartupfile);
/* Load the encoding file */
if (optfontencoding == 0)
{ pstrace("% Loading encoding file\n");
pssintf("/encoding StandardEncoding 256 array copy def\n");
pssintf("[ (%.100s) run ] aload length 2 idiv\n", argencodingfile);
pssintf("{ encoding 3 1 roll put } repeat\n");
}
/* Load the font. Make sure we don't get a substitute */
pstrace("%% Loading font\n");
pssintf("/fontname /%.100s def\n", argfontname);
pssintf("fontname findfont pop\n");
pssintf("/font fontname .findfont def\n");
/* Encode the font */
pstrace("%% Encoding font\n");
pssintf("/newfont font maxlength dict def\n");
pssintf("font\n"
"{ exch dup /FID ne "
"{ exch newfont 3 1 roll put } { pop pop } ifelse }\n"
"forall\n");
if (optfontencoding == 0)
pssintf("newfont /Encoding encoding put\n");
pssintf("/_%.100s newfont definefont pop\n", argfontname);
if (pserror != 0) goto pserror;
pstrace("%% LoChar = %d; HiChar = %d\n", lochar, hichar);
/* Determine the bounding boxes for all the characters */
pstrace("%% Generating bounding boxes\n");
pssintf("/cstr 1 string def\n");
pssintf("newfont 1000 scalefont setfont\n");
pssintf("%d 1 %d\n"
"{ /i exch def cstr 0 i put null i\n"
" 0 0 moveto cstr false charpath pathbbox newpath\n"
" 4 { round cvi 4 1 roll } repeat\n"
" 5 0 callextfunc\n"
"} for\n", lochar, hichar);
if (pserror != 0) goto pserror;
/* Position the baseline, if we have not set it explicitly */
if (optbaseline == -1)
{
/* This is what we have room for */
zz = (1000 * 72) / optyden;
/* Calculate the lower and upper limits of the whole character set */
z1 = z2 = 0;
for (i = 0; i <= 255 ; i++)
{ if (lly[i] < z1) z1 = lly[i];
if (ury[i] > z2) z2 = ury[i];
}
if (z2 == z1)
{ fprintf(stderr, "mkbmap: all characters in the font are null\n");
goto errorexit;
}
/* If we have room for everything, or the font has a non-standard
* character set, set the baseline in proportion to the relative
* sizes of the ascenders and descenders */
optbaseline = (1000 * (-z1) + (z2 - z1) / 2) / (z2 - z1);
/* Otherwise, for fonts with standard character sets, calculate the
* limits of the alphabet. If we have room for that then leave just
* enough room for the descenders, or else set the baseline
* proportionately */
if (z2 - z1 > zz && optfontencoding == 0)
{ y1 = y2 = 0;
for (i = 'A'; i <= 'Z' ; i++)
{ if (lly[i] < y1) y1 = lly[i];
if (ury[i] > y2) y2 = ury[i];
}
for (i = 'a'; i <= 'z' ; i++)
{ if (lly[i] < y1) y1 = lly[i];
if (ury[i] > y2) y2 = ury[i];
}
if (y2 - y1 <= zz)
optbaseline = (1000 * (-y1) + zz / 2) / zz;
else
optbaseline = (1000 * (-y1) + (y2 - y1) / 2) / (y2 - y1);
}
pstrace("%% Baseline set at %d/1000 of the pixel height\n",
optbaseline);
}
/* Validate the font file name and create the font subdirectory */
if (buildfdirname(namebuf, argbmapfile, 0) == NULL)
{ fprintf(stderr, "mkbmap: bmap file has no directory path\n");
goto errorexit;
}
if (optnew)
{ fdlock = CreateDir(namebuf);
if (fdlock)
{ UnLock(fdlock);
fdlock = 0;
}
}
/* Loop through all the point sizes */
for (pointn = 0; pointn < pointc; pointn++)
{ if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) goto broken;
pointsize = pointv[pointn];
pstrace("%% Point size %d\n", pointsize);
baseline = (pointsize * optbaseline + 500) / 1000;
if (baseline < 0) baseline = 0;
if (baseline > pointsize - 1) baseline = pointsize - 1;
/* Build the bitmapped font in memory. Estimate the maximum
* possible width of the bitmap from the total widths of the
* bounding boxes, allowing 2 extra pixels per character for
* rounding and stem alignment. Calculate the mamimum font
* length, allocate the memory, and initialise the headers */
baselen = 4 + sizeof (struct DiskFontHeader) +
8 * (hichar - lochar + 2);
maxwidth = 0;
for (ch = lochar; ch <= hichar ; ch++)
maxwidth +=
((urx[ch] - llx[ch]) * pointsize * optxden) / 72000 + 2;
maxmodulo = ((maxwidth + 15) >> 3) & ~1;
maxcharlen = maxmodulo * pointsize;
maxfontlen = baselen + maxcharlen + 2 + 76;
fontmem = AllocMem(maxfontlen, MEMF_PUBLIC|MEMF_CLEAR);
if (fontmem == NULL)
{ fprintf(stderr, "mkbmap: can't get font memory\n");
goto errorexit;
}
hunkptr = fontmem;
dfheader = (void *) &hunkptr[9];
charloc = (void *) &dfheader[1];
charspace = (void *) &charloc[(hichar - lochar + 2) * 2];
charkern = (void *) &charspace[hichar - lochar + 2];
chardata = (void *) &charkern[hichar - lochar + 2];
/* Set up the bitmap to render the characters */
pstrace("%% Rendering bitmaps\n");
parm.page.buf[0] = (char *) chardata;
parm.page.len = maxcharlen;
parm.page.depth = 1;
parm.page.xoff = 0;
parm.page.yoff = 0;
parm.page.xbytes = maxmodulo;
parm.page.xsize = maxwidth;
parm.page.ysize = pointsize;
parm.page.ybase = 0;
parm.page.yheight = pointsize;
PSsetdevice(arec, &parm.page);
pssintf("initmatrix\n");
pssintf("/xscale %d %d mul 72 div def\n", pointsize, optxden);
pssintf("/yscale %d %d mul 72 div def\n", pointsize, optyden);
pssintf("newfont [ xscale 0 0 yscale 0 0 ] makefont setfont\n");
actwidth = 0;
nomwidth = 0;
nomcount = 0;
/* Loop to render each character. We estimate the bounds of the
* characters conservatively (hinting any shift them a little) and
* trim the bitmap if possible. We clip on the left, so any part
* of the character projecting to the left is truncated, and does
* not overwrite the previous one. We erase the character cell so
* it does not matter if the clipping of the right of the previous
* character was not complete. We render the portiona above and
* below the baseline separately, so they can be indepently scaled
* to fit */
for (ch = lochar; ch <= hichar; ch++)
{ z1 = (llx[ch] * pointsize * optxden - 41000) / 72000;
z2 = (urx[ch] * pointsize * optxden + 41000) / 72000;
if (z1 < 0) z1 = 0;
pssintf("cstr 0 %d put\n", ch);
pssintf("%d %d moveto\n", actwidth, baseline);
pssintf("gsave %d 0 rlineto 0 %d rlineto "
"-%d 0 rlineto closepath clip\n",
z2, -baseline, z2);
pssintf("1 setgray fill 0 setgray\n");
pssintf("%d %d moveto ", actwidth - z1, baseline);
y1 = ((-lly[ch]) * pointsize * optxden) / 72;
y2 = baseline * 1000;
if (y1 > y2)
pssintf("1 %d %d div scale\n", y2, y1);
pssintf("cstr show\n"
"grestore\n");
pssintf("gsave %d 0 rlineto 0 %d rlineto "
"-%d 0 rlineto closepath clip\n",
z2, pointsize - baseline, z2);
pssintf("1 setgray fill newpath 0 setgray\n");
pssintf("%d %d moveto ", actwidth - z1, baseline);
y1 = (ury[ch] * pointsize * optxden) / 72;
y2 = (pointsize - baseline) * 1000;
if (y1 > y2)
pssintf("1 %d %d div scale\n", y2, y1);
pssintf("cstr show\n"
"null currentpoint 2 { round cvi exch } repeat "
"2 1 callextfunc\n"
"grestore\n");
ww = cposx - actwidth;
zz = z2 - z1;
if (zz > ww) zz = ww;
i = ch - lochar;
charloc[i * 2] = actwidth;
charloc[i * 2 + 1] = zz;
charspace[i] = ww;
charkern[i] = z1;
actwidth += zz;
if (lly[ch] != ury[ch])
{ nomwidth += z1 + ww;
nomcount++;
}
if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
goto broken;
}
if (pserror != 0) goto pserror;
/* If we have not explicitly set the nominal character width,
* calculate it as the average width of the non-null characters
* we have generated */
if (optwidth == -1)
{ if (nomcount != 0)
nomwidth = (nomwidth + nomcount / 2) / nomcount;
}
else
nomwidth = (optwidth * pointsize * optxden + 36000) / 72000;
/* We now know the actual width, so we can calculate the actual
* modulo and file lengths. Then we must reformat the bitmap to
* the new width */
if (actwidth > maxwidth)
{ fprintf(stderr, "mkbmap: width estimate exceeded\n");
goto errorexit;
}
actmodulo = ((actwidth + 15) >> 3) & ~1;
actcharlen = actmodulo * pointsize;
hunklen = baselen + actcharlen;
if (hunklen & 2) hunklen += 2;
hunknum = hunklen >> 2;
actfontlen = hunklen + 76;
i = 1;
s = chardata + maxmodulo;
t = chardata + actmodulo;
while (i < pointsize)
{ l = actmodulo;
while (l--) *t++ = *s++;
i++;
s += (maxmodulo - actmodulo);
}
/* Finish the bitmapped font. Write it out to the file */
buildfdirname(namebuf, argbmapfile, 2);
hunkptr[0] = Hunk_Header;
hunkptr[1] = 0;
hunkptr[2] = 1;
hunkptr[3] = 0;
hunkptr[4] = 0;
hunkptr[5] = hunknum;
hunkptr[6] = Hunk_Code;
hunkptr[7] = hunknum;
hunkptr += 8;
hunkptr[0] = MOVFFD0RTS;
dfheader->dfh_DF.ln_Type = NT_FONT;
dfheader->dfh_DF.ln_Name = (char *) 0x0000001A;
dfheader->dfh_FileID = DFH_ID;
strncpy((char *)&dfheader->dfh_Name, namebuf, MAXFONTNAME);
dfheader->dfh_TF.tf_Message.mn_Node.ln_Type = NT_FONT;
dfheader->dfh_TF.tf_Message.mn_Node.ln_Name = (char *) 0x0000001A;
dfheader->dfh_TF.tf_Message.mn_Length = hunklen - 58;
dfheader->dfh_TF.tf_YSize = pointsize;
dfheader->dfh_TF.tf_Style =
(optbold ? FSF_BOLD : 0) | (optitalic ? FSF_ITALIC : 0);
dfheader->dfh_TF.tf_Flags =
(optmonospaced ? 0 : FPF_PROPORTIONAL) | FPF_DESIGNED;
dfheader->dfh_TF.tf_XSize = nomwidth;
dfheader->dfh_TF.tf_Baseline = pointsize - baseline - 1;
dfheader->dfh_TF.tf_BoldSmear = pointsize / 20 + 1;
dfheader->dfh_TF.tf_LoChar = lochar;
dfheader->dfh_TF.tf_HiChar = hichar;
dfheader->dfh_TF.tf_CharData =
(APTR) ((char *) chardata - (char *) hunkptr);
dfheader->dfh_TF.tf_Modulo = actmodulo;
dfheader->dfh_TF.tf_CharLoc =
(APTR) ((char *) charloc - (char *) hunkptr);
dfheader->dfh_TF.tf_CharSpace =
(APTR) ((char *) charspace - (char *) hunkptr);
dfheader->dfh_TF.tf_CharKern =
(APTR) ((char *) charkern - (char *) hunkptr);
hunkptr += hunknum;
hunkptr[0] = Hunk_Reloc32;
hunkptr[1] = 6;
hunkptr[2] = 0;
hunkptr[3] = 0x0000006A;
hunkptr[4] = 0x00000066;
hunkptr[5] = 0x00000062;
hunkptr[6] = 0x0000005C;
hunkptr[7] = 0x00000044;
hunkptr[8] = 0x0000000E;
hunkptr[9] = 0;
hunkptr[10] = Hunk_End;
pstrace("%% Writing bmap file\n");
if (buildfnumname(namebuf, argbmapfile, pointsize) == NULL)
{ fprintf(stderr, "mkbmap: bmap file name too long\n");
goto errorexit;
}
newfh = Open(namebuf, MODE_NEWFILE);
if (newfh == NULL)
{ fprintf(stderr, "mkbmap: can't open bmap file %s\n", namebuf);
goto errorexit;
}
i = Write(newfh, (UBYTE *) fontmem, actfontlen);
Close(newfh);
if (i == -1)
{ fprintf(stderr, "mkbmap: error writing bmap file %s\n", namebuf);
goto errorexit;
}
}
/* Update font contents file */
newfont:
if (optnew)
{ pstrace("%% Updating font contents file\n");
buildfdirname(namebuf, argbmapfile, 1);
fdlock = Lock(namebuf, SHARED_LOCK);
if (fdlock == NULL)
{ fprintf(stderr, "mkbmap: can't lock font directory %s\n",
namebuf);
goto errorexit;
}
buildfdirname(namebuf, argbmapfile, 2);
strcat(namebuf, ".font");
DiskfontBase = OpenLibrary("diskfont.library", 34);
if (DiskfontBase) fcheader = NewFontContents(fdlock, namebuf);
if (fcheader == NULL)
{ fprintf(stderr, "mkbmap: can't create new font contents %s\n",
namebuf);
goto errorexit;
}
if (fcheader->fch_NumEntries == 0)
{ fprintf(stderr, "mkbmap: font %s directory contains no fonts\n",
namebuf);
retcode = 10;
goto tidyexit;
}
/* Swap to the font directory, update the file, and swap back */
cdlock = CurrentDir(fdlock);
newfh = Open(namebuf, MODE_NEWFILE);
if (newfh)
{ i = Write(newfh, (UBYTE *)fcheader,
sizeof (struct FontContentsHeader) +
sizeof (struct FontContents) * fcheader->fch_NumEntries);
Close(newfh);
}
CurrentDir(cdlock);
if (newfh == NULL)
{ fprintf(stderr, "mkbmap: can't open font contents file %s\n",
namebuf);
goto errorexit;
}
else if (i == -1)
{ fprintf(stderr, "mkbmap: error writing font contents file %s\n",
namebuf);
goto errorexit;
}
/* Tidy up */
DisposeFontContents(fcheader);
fcheader = NULL;
CloseLibrary(DiskfontBase);
DiskfontBase = NULL;
UnLock(fdlock);
fdlock = NULL;
}
/* All done */
pstrace("%% All done\n");
goto tidyexit;
/* Argument errors and usage query */
query:
fprintf(stderr, "Bitmap font generator. MkBmap version 1.0\n"
"Makes Amiga bitmapped fonts from PostScript fonts\n"
"\n"
" Usage:\n"
"\n"
" mkbmap -options bmapfile fontname nn,nn,...\n"
"\n"
" -s startupfile Startup file name\n"
" -e encodingfile Encoding file name\n"
" -f Font specific encoding\n"
" -n Make new .font contents\n");
fprintf(stderr, " -dnnn Density: x and y (dpi)\n"
" -xnnn Density: x (dpi)\n"
" -ynnn Density: y (dpi)\n"
" -znnn Baseline (1/1000)\n"
" -wnnn Width (1/1000)\n"
" -lnnn LoChar\n"
" -hnnn Hichar\n"
" -m Monospaced\n"
" -b Bold\n"
" -i Italic\n"
" -t Trace (for debuggindg)\n"
"\n"
" For example:\n"
"\n"
" mkbmap -n fonts:Times/* Times-Roman 10,12,14\n");
goto tidyexit;
badargs:
fprintf(stderr, "mkbmap: arguments bad, or value missing");
badusage:
retcode = 20;
fprintf(stderr, ". Usage:\n"
" mkbmap -options bmapfile fontname nn,nn,...\n");
goto tidyexit;
/* PostScript library error */
pserror:
fprintf(stderr, "mkbmap: post.library interpreter error\n");
goto errorexit;
/* Tidy up and exit */
broken:
fprintf(stderr, "mkbmap: *** Break\n");
retcode = 10;
goto tidyexit;
errorexit:
retcode = 20;
tidyexit:
if (ftrapset)
{ deleteftrap();
ftrapset = 0;
}
if (arec) PSdeleteact(arec);
if (PSbase) CloseLibrary(PSbase);
if (fontmem) FreeMem(fontmem, maxfontlen);
if (fcheader) DisposeFontContents(fcheader);
if (DiskfontBase) CloseLibrary(DiskfontBase);
if (fdlock) UnLock(fdlock);
exit(retcode);
}
/* String to integer conversion; digits only, with error check */
int strtoint(char **sp, int *ip)
{ char *s = *sp;
int i = 0;
int ch;
for (;;)
{ ch = *s;
if (ch < '0' || ch > '9') break;
i = i * 10 + (ch - '0');
s++;
}
if (s == *sp)
return 0;
else
{ *sp = s;
*ip = i;
return 1;
}
}
/* Build the bitmap font file name. Copy it, replacing "*" by the point
* size. Then scan it backwards replacing "?" by digits */
char *buildfnumname(char *nbuf, char *name, int num)
{ char number[10];
int numlen, i, j, k, ch;
numlen = 0;
while (num)
{ number[numlen++] = num % 10 + '0';
num /= 10;
}
i = j = 0;
for (;;)
{ if (j > 100) return NULL;
ch = name[i++];
if (ch == '*')
{ k = numlen;
while (k--) nbuf[j++] = number[k];
}
else
nbuf[j++] = ch;
if (ch == 0) break;
}
k = 0;
while (--j)
{ if (nbuf[j] == '?')
nbuf[j] = (k < numlen) ? number[k++] : '0';
}
return nbuf;
}
/* Build the font file/directory name. We copy it, striping off the last
* two components:
*
* type = 0: fontdir/fontname/* => fontdir/fontname
* type = 1: fontdir/fontname/* => fontdir
* type = 2: fontdir/fontname/* => fontname
*
* (or fontdir:fontname/* => ...)
*/
char *buildfdirname(char *nbuf, char *name, int type)
{ int i, j, k;
i = strlen(name);
for (;;)
{ if (i == 0) return NULL;
i--;
if (name[i] == ':') return NULL;
if (name[i] == '/') break;
}
j = i;
for (;;)
{ if (j == 0) return NULL;
j--;
if (name[j] == ':')
{ k = j = j + 1;
break;
}
if (name[j] == '/')
{ k = j;
j = j + 1;
break;
}
}
if (k == 0) return NULL;
if (i >= 100) return NULL;
if (type == 1)
i = k;
else if (type == 2)
{ name += j;
i -= j;
}
memcpy(nbuf, name, i);
nbuf[i] = 0;
return nbuf;
}
/* Trace output */
void pstrace(char *format, ...)
{ va_list ap;
if (pserror != 0) return;
if (opttrace)
{ va_start(ap, format);
vfprintf(stdout, format, ap);
fflush(stdout);
va_end(ap);
}
}
/* Interpret postscript string */
void pssintf(char *format, ...)
{ va_list ap;
if (pserror != 0) return;
va_start(ap, format);
if (opttrace)
{ vfprintf(stdout, format, ap);
fflush(stdout);
}
vsprintf(psstring, format, ap);
pserror = PSintstring(arec, psstring, -1, PSFLAGSTRING)
va_end(ap);
}
/* Set character bounding box */
void __saveds setbbox(int ch, int lx, int ly, int rx, int uy)
{ llx[ch] = lx;
lly[ch] = ly;
urx[ch] = rx;
ury[ch] = uy;
}
/* Set current point */
void __saveds setcpos(int cpx, int cpy)
{ cposx = cpx;
cposy = cpy;
}
/* Signal an interrupt */
void __saveds sigint()
{ PSsignalint(arec, 1);
}
/* Signal a floating point error */
void __saveds sigfpe()
{ PSsignalfpe(arec);
}
/* Dummy stub routine */
void stub(void)
{ return;
}
/* Dummy check abort routine */
void chkabort(void)
{ return;
}
/* End of file "mkbmap.c" */